package builder

import (
	"errors"
	"fmt"
)

// Tesla 特斯拉
// 初始化很麻烦，有很多参数，vin是必填，其他是选填，长>宽>高
// 怎么初始化? 使用建造者模式
type Tesla struct {
	vin   string
	model string
	price float32
	color string
	lwh   *LWH
}

func (t *Tesla) Print() {
	res := fmt.Sprintf("tesla: %s, price: %.2f, model: %s, color: %s", t.vin, t.price, t.model, t.color)
	fmt.Println(res)
}

type LWH struct {
	length float32
	width  float32
	height float32
}

func NewLWH(length, width, height float32) (*LWH, error) {
	if length < width || width < height {
		return nil, errors.New("lwh不正确")
	}
	return &LWH{
		length: length,
		width:  width,
		height: height,
	}, nil
}

func NewTesla() *Tesla {
	return &Tesla{}
}

type TeslaBuilder struct {
	tesla *Tesla
}

func NewTeslaBuilder() *TeslaBuilder {
	return &TeslaBuilder{
		tesla: NewTesla(),
	}
}

func (t *TeslaBuilder) SetVIN(vin string) *TeslaBuilder {
	t.tesla.vin = vin
	return t
}

func (t *TeslaBuilder) SetModel(model string) *TeslaBuilder {
	t.tesla.model = model
	return t
}

func (t *TeslaBuilder) SetPrice(price float32) *TeslaBuilder {
	t.tesla.price = price
	return t
}

func (t *TeslaBuilder) SetColor(color string) *TeslaBuilder {
	t.tesla.color = color
	return t
}

//func (t *TeslaBuilder) SetLWH(lwh *LWH) *TeslaBuilder {
//	t.tesla.lwh = lwh
//	return t
//}

func (t *TeslaBuilder) SetLWH(length, width, height float32) *TeslaBuilder {
	t.tesla.lwh = &LWH{length: length, width: width, height: height}
	return t
}

func (t *TeslaBuilder) Build() (*Tesla, error) {
	if t.tesla.vin == "" {
		return nil, errors.New("vin is required")
	}

	if t.tesla.price < 0.0 {
		return nil, errors.New("price invalid")
	}
	if t.tesla.lwh != nil {
		if t.tesla.lwh.length < t.tesla.lwh.width {
			return nil, errors.New("lwh不正确")
		}
	}

	return t.tesla, nil
}
